package com.kitty.game.fight.util;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.fight.SkillConst;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.bean.FightObject;
import com.kitty.game.skill.model.RoleSkill;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * 技能目标采集器
 */
public class SkillTargetPicker {

    /**
     * 获取攻击的地方单元
     *
     * @param effector  施法者
     * @param maxTarget 出手数量
     * @param fight     战场
     * @return
     */
    public static List<Integer> getRandomAttackTarget(Fight fight, FightObject effector, int maxTarget) {
        List<Integer> targets = new ArrayList<>();
        FightObject target = fight.queryFightObject(effector.getTargetId());
        if (target != null && target.getCurrLife() > 0 && target.isASide() != effector.isASide()) {
            targets.add(target.getId());
        }
        if (targets.size() >= maxTarget) {
            return targets;
        }
        // 取目标列表
        List<FightObject> allEnemies = fight.getTargetSide(effector.getId());

        ArrayList<Integer> otherTargets = new ArrayList<>();
        for (FightObject tempFightObject : allEnemies) {
            if (target == tempFightObject) {
                continue;
            }
            if (tempFightObject.getCurrLife() <= 0) {
                continue;
            }
            otherTargets.add(tempFightObject.getId());
        }
        if (allEnemies.isEmpty()) {
            return targets;
        }

        Collections.shuffle(otherTargets);

        int size = maxTarget - targets.size();
        size = Math.min(size, otherTargets.size());

        targets.addAll(otherTargets.subList(0, size));
        return targets;
    }

    /**
     * 十字架技能目标
     *
     * @param fight
     * @param effector
     * @param maxTarget
     * @return
     */
    public static List<Integer> getCrossAttackTarget(Fight fight, FightObject effector, int maxTarget) {
        Set<Integer> targetSet = new HashSet<>();
        FightObject target = fight.queryFightObject(effector.getTargetId());
        if (target != null && target.getCurrLife() > 0 && !fight.isSameSide(effector, target)) {
            targetSet.add(target.getId());
        }
        if (targetSet.size() >= maxTarget) {
            return new ArrayList<>(targetSet);
        }
        if (target == null) {
            target = SpringUtils.getFightService().getPhysicTarget(effector, fight);
            if (target == null) {
                /**如果重新取目标还是没有 直接返回*/
                return new ArrayList<>();
            }
        }
        /**主目标死亡之后需要重新设置主目标*/
        effector.setTargetId(target.getId());
        int centerPos = target.getPos();
        List<Integer> crossTargets = pickUpCrossTargets(centerPos,maxTarget);
        // 站位与对应的角色id
        Map<Integer, Integer> pos2Actors = new HashMap<>();

        for (FightObject obj : fight.getTargetSide(effector.getId())) {
            pos2Actors.put(obj.getPos(), obj.getId());
        }

        for (Integer pos : crossTargets) {
            int targetId = pos2Actors.getOrDefault(pos, 0);
            if (targetId <= 0) {
                continue;
            }
            FightObject tmpObj = fight.queryFightObjectAnyWay(targetId);
            if (tmpObj == null || tmpObj.isFallDown() || fight.isSameSide(effector, tmpObj)) {
                continue;
            }
            targetSet.add(targetId);
            if (targetSet.size() >= maxTarget) {
                break;
            }
        }

        if (targetSet.size() < maxTarget) {
//            LoggerFunction.FIGHT.getLogger().info("力破最大目标{}, 顺序{} 主目标{} 位置{} 命中{}", maxTarget, crossTargets, target.getPos(), pos2Actors, targetSet.toString());
        }

        return new ArrayList<>(targetSet);
    }

    private static List<Integer> pickUpCrossTargets(int pos,int maxTarget) {
        List<Integer> orders = new ArrayList<>();
        orders.add(pos);
        if (inRange(6, 10, pos)) {
            orders.add(pos - 5);
            for (int i = 1; i <= 4; i++) {
                if (inRange(6, 10, pos - i)) {
                    orders.add(pos - i);
                }
                if (inRange(6, 10, pos + i)) {
                    orders.add(pos + i);
                }
            }
        }

        if (inRange(1, 5, pos)) {
            orders.add(pos + 5);
            for (int i = 1; i <= 4; i++) {
                if (inRange(1, 5, pos - i)) {
                    orders.add(pos - i);
                }
                if (inRange(1, 5, pos + i)) {
                    orders.add(pos + i);
                }
            }
        }
        if (maxTarget > 6){
            for (int i = 1; i <= 10; i++){
                if (orders.size() >= maxTarget){
                    return orders;
                }
                if (orders.contains(i)){
                    continue;
                }
                orders.add(i);
            }
        }

        return orders;
    }

    private static boolean inRange(int l, int r, int v) {
        return l <= v && v <= r;
    }

    /**
     * 获得辅助的己方单元
     *
     * @param effector  施法者
     * @param maxTarget
     * @param fight
     * @return
     */
    public static List<Integer> getAssistTarget(Fight fight, FightObject effector, int maxTarget) {
        FightObject target = fight.queryFightObject(effector.getTargetId());
        List<FightObject> selfList = fight.getMySide(effector.getId());
        ArrayList<String> aliveList = new ArrayList<>();
        ArrayList<Integer> resultList = new ArrayList<>();
        RoleSkill roleSkill = effector.getSkillBy(effector.getSkillId());

        if (effector.getPolar() == 2 || roleSkill.getSkillId() == SkillConst.SKILL_SHE_SHEN) {
            // 木系的辅助技能加血- 舍身取义 ,可以选择挂了的目标 主目标只要存在,就可以使用
            if (target != null && SpringUtils.getFightService().isSameTeam(effector, target)) {
                resultList.add(target.getId());
            }
            if (resultList.size() >= maxTarget) {
                return resultList;
            }
            for (FightObject tempfightObject : selfList) {
                if (!resultList.contains(tempfightObject.getId())) {
                    aliveList.add(tempfightObject.getId() + "");
                }
            }

        } else {
            // 非木系的辅助技能,只能选择活着的目标
            if (target != null && target.getCurrLife() > 0 && SpringUtils.getFightService().isSameTeam(effector, target)) {
                resultList.add(target.getId());
            }
            for (FightObject temp : selfList) {
                if (temp.getCurrLife() > 0 && !resultList.contains(temp.getId())) {
                    aliveList.add(temp.getId() + "");
                }
            }
        }

        Random random = new Random();
        int size = maxTarget - resultList.size();
        for (int i = 0; i < size; i++) {
            if (aliveList.size() <= 0) {
                return resultList;
            }
            if (resultList.size() >= maxTarget) {
                return resultList;
            }
            int index = random.nextInt(aliveList.size());
            String value = aliveList.get(index);
            resultList.add(Integer.parseInt(value));
            aliveList.remove(value);
        }
        return resultList;
    }


}
